﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.IO;
using System.Linq;
using System.Threading;
using System.Diagnostics;
using System.Collections.Generic;

namespace System.Windows.Media.DirectShow.Filters
{
    internal class PinTeeInputPin : BaseInputPin
    {

        private AMMediaType[] _mediaTypes = new AMMediaType[] { new AMMediaType {
            MajorType = MediaMajorTypes.None,
            SubType = MediaSubTypes.None,
        }};

        private PinTee filter;

        public PinTeeInputPin(PinTee filter)
            : base(filter)
        {
            this.filter = filter;
        }

        public override bool ReceiveCanBlock
        {
            get { return false; }
        }

        protected override void ReceiveConnection(IPin connector, AMMediaType mediaType)
        {
            base.ReceiveConnection(connector, mediaType);

            foreach (PinTeeOutputPin oPin in this.filter.Pins.FindByDirection(PinDirection.Output))
            {
                oPin.SetMediaTypes(new AMMediaType[] { this.ConnectedMediaType });
            }
        }

        protected override void Receive(IMediaSample sample)
        {
            sample.AddRef();

            try
            {
                this.filter.Pins.ExecuteAction<PinTeeOutputPin>(p =>
                {
                    p.ProcessSample(sample);
                });

                if (this.IsPullMode)
                    this.RequestNextSample(sample);
            }
            finally
            {
                sample.Release();
            }
        }

        protected override void EndOfStream()
        {
            base.EndOfStream();

            this.filter.Pins.ExecuteAction<PinTeeOutputPin>(p =>
            {
                p.DeliverEndOfStream();
            });
        }

        protected override bool QueryAccept(AMMediaType mediaType)
        {
            return true;
        }

        protected override AllocatorProperties GetAllocatorRequirements()
        {
            // Use first pin
            IMemInputPin ip = this.filter.Pins.OfType<PinTeeOutputPin>().Select(p => p.ConnectedPin).OfType<IMemInputPin>().FirstOrDefault();
            if (ip != null)
                return ip.GetAllocatorRequirements();

            return base.GetAllocatorRequirements();
        }

        public override System.Collections.Generic.IEnumerable<AMMediaType> MediaTypes
        {
            get { return _mediaTypes; }
        }

        public override string Name
        {
            get { return "Infinite Pin Tee Filter Input pin"; }
        }
    }
}
